/*
 * Copyright 2009 Andrey Khalzov, and individual contributors as indicated by the @author tag.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and limitations under the License.
 */

package org.wannatrak.test.encoder.sample;

import org.wannatrak.GpsData;
import org.wannatrak.test.encoder.GpsDataEncoder;

/**
 * Created 14.12.2009 0:16:01
 *
 * @author Andrey Khalzov
 */
public class SampleGpsDataEncoder implements GpsDataEncoder {

    private static final int COORDS_MULTIPLIER = 1000000;

    @Override
    public byte[] encode(GpsData... gpsData) {
        if (gpsData == null || gpsData.length == 0) {
            return new byte[0];
        }

        final String id = gpsData[0].getSourceId();
        if (id == null) {
            return new byte[0];
        }

        final int idLength = gpsData[0].getSourceId().length();

        final byte[] packet = new byte[4 + idLength + gpsData.length * 22];
        packet[0] = 1;

        packet[1] = (byte) idLength;

        System.arraycopy(id.getBytes(), 0, packet, 2, id.length());

        packet[2 + idLength] = (byte) ((gpsData.length & 0xFF00) >> 8);
        packet[3 + idLength] = (byte) (gpsData.length & 0xFF);

        for (int i = 0; i < gpsData.length; i++) {
            final GpsData data = gpsData[i];

            int base = 4 + idLength + i * 22;

            putLongToPacket(packet, base, data.getTimestamp());

            putIntToPacket(packet, base + 8, (int) (data.getLatitude() * COORDS_MULTIPLIER));
            putIntToPacket(packet, base + 12, (int) (data.getLongitude() * COORDS_MULTIPLIER));

            putShortToPacket(packet, base + 16, (short) (data.getAltitude()));
            putShortToPacket(packet, base + 18, (short) (data.getSpeedKph() * 10));
            putShortToPacket(packet, base + 20, (short) data.getHeading());
        }

        return packet;
    }

    private void putLongToPacket(byte[] packet, int offset, long value) {
        putIntToPacket(packet, offset, (int) (value >> 32));
        putIntToPacket(packet, offset + 4, (int) value);
    }

    private void putIntToPacket(byte[] packet, int offset, int value) {
        packet[offset] = (byte) ((value & 0xFF000000) >> 24);
        packet[offset + 1] = (byte) ((value & 0xFF0000) >> 16);
        packet[offset + 2] = (byte) ((value & 0xFF00) >> 8);
        packet[offset + 3] = (byte) (value & 0xFF);
    }

    private void putShortToPacket(byte[] packet, int offset, short value) {
        packet[offset] = (byte) ((value & 0xFF00) >> 8);
        packet[offset + 1] = (byte) (value & 0xFF);
    }
}
